package demo5;

import com.google.common.collect.Lists;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightMethodBuilder;
import org.apache.commons.lang3.ObjectUtils;

import java.util.ArrayList;
import java.util.List;

public class LombokPsiUtils {
    public static PsiAnnotation getAnnotation(PsiClass psiClass, String annoName) {
        PsiAnnotation annotation = psiClass.getAnnotation(annoName);
        return  annotation;
    }

    public static List<PsiField> getFields(PsiClass psiClass) {
        List<PsiField> fields = new ArrayList<>();
        PsiField[] fieldArr = psiClass.getFields();
        if(fieldArr != null){
            for (PsiField field : fieldArr) {
                boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
                if(!isStatic){
                    boolean isPrivateOrProtected = field.hasModifierProperty(PsiModifier.PRIVATE)||field.hasModifierProperty(PsiModifier.PROTECTED);
                    if(isPrivateOrProtected){
                        fields.add(field);
                    }
                }
            }
        }
        return fields;
    }

    public static  PsiType getPsiType(PsiClass psiClass,String type){
        Project project = psiClass.getProject();
        PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(project);
        PsiType psiType = psiElementFactory.createTypeFromText(type, null);
        return psiType;
    }


    public static  PsiMethod createCacheMethod(PsiClass psiClass,String methodName,List<PsiParameter> parameterList,PsiType returnType,PsiField field) {
        PsiManager psiManager = psiClass.getContainingFile().getManager();

        LightMethodBuilder lightMethodBuilder = new LightMethodBuilder(psiManager, JavaLanguage.INSTANCE, methodName);
        lightMethodBuilder.addModifier(PsiModifier.PUBLIC);
        lightMethodBuilder.setContainingClass(psiClass);
        if (ObjectUtils.isNotEmpty(parameterList)) {
            for (PsiParameter psiParameter : parameterList) {
                lightMethodBuilder.addParameter(psiParameter.getName(), psiParameter.getType());
            }
        }
        lightMethodBuilder.setMethodReturnType(returnType);
        lightMethodBuilder.setContainingClass(psiClass);
        lightMethodBuilder.setNavigationElement(field);
        //boolean has = haveMethod(psiClass, methodName, parameterList, returnType);
        return lightMethodBuilder;
    }

    public static  boolean haveMethod(PsiClass psiClass,String methodName,List<PsiParameter> parameterList,PsiType returnType){
        boolean bRet = false;
        PsiMethod[] psiMethods = psiClass.getAllMethods();
        for (PsiMethod psiMethod : psiMethods) {
            if (methodName.equals(psiMethod.getName())) {
                PsiType psiType = psiMethod.getReturnType();
                if (psiType.equals(returnType) == false){
                    return bRet;
                }
                PsiParameterList psiParameterList = psiMethod.getParameterList();

                if (ObjectUtils.isEmpty(parameterList)){
                    parameterList = Lists.newArrayList();
                }

                if (parameterList.size() != psiParameterList.getParameters().length){
                    return bRet;
                }

                int i = 0;
                for(PsiParameter parameter : parameterList){
                    PsiParameter psiParameter = psiParameterList.getParameter(i);
                    if (parameter.getName().equals(psiParameter.getName()) == false){
                        return bRet;
                    }

                    if (parameter.getType().equals(psiParameter.getType()) == false){
                        return bRet;
                    }

                    i++;

                }
                bRet = true;
                break;
            }
        }
        return bRet;
    }
}
